#include "bmp.h"

int main(int argc, char const *argv[])
{
    // 指定一张bmp图片
    if(argc != 2){
        printf("请指定一张BMP图片！\n");exit(0);
    }

    // 打开LCD设备
    int lcd = open("/dev/ubuntu_lcd", O_RDWR);
    if(lcd == -1){
        perror("LCD屏幕打开失败");exit(0);
    }

    // 映射内存
    char *p = mmap(NULL, 800*480*4, PROT_WRITE, MAP_SHARED, lcd, 0);
    if(p == MAP_FAILED){
		perror("映射内存失败");exit(0);
	}
    // 内存清零
    bzero(p,800*480*4);

    FILE *fp = fopen(argv[1], "r");
    if(!fp){
        perror("BMP图片打开失败！");exit(0);
    }

    // 读取BMP图片的头部信息
    struct bitmap_header head;
    struct bitmap_info   info;

    bzero(&head, sizeof(head));
    bzero(&info, sizeof(info));
    //读取文件信息
    fread(&head, sizeof(head), 1, fp);
    fread(&info, sizeof(info), 1, fp);

    // 展示图片的信息
    printf("图片文件大小:%d\n", head.size);
    printf("图片尺寸: %d × %d\n", info.width, info.height);
    printf("图片色深:%d\n", info.bit_count);

    // 计算每行末尾的无效字节数
    int n = (4-((info.width*(info.bit_count/8))%4)) % 4;
    printf("无效字节：%d\n", n);

    // 计算每行实际的大小（包括无效字节）
    int lineBytes = info.width * (info.bit_count/8) + n;
    // 计算整个RGB数据（包括无效字节）的大小
    int rgbSize = lineBytes * info.height;

    printf("RGB数据（包括无效字节）的大小：%d\n", rgbSize);

    if(info.compression){
        struct rgb_quad q;
        fread(&q, sizeof(q), 1, fp);
    }

    // 读取BMP图片中的RGB数据
    char *rgb = calloc(1,  rgbSize);
    fread(rgb, rgbSize, 1, fp);
    
    //图片自适应
    int p_wd=1,p_ht=1;
    if(info.width>800){
        p_wd=info.width/800;
    }
    if(info.height>480){
        p_ht=info.height/480;
    }
    //计算居中显示起始坐标
    int mid_x = 0,mid_y = 0;
    if(info.width<800 && info.height < 480){
        mid_x = (800 - info.width)/2;
        mid_y = (480 - info.height)/2;
    }

    // 因为BMP图像信息倒置原因，需要翻转
    // 让tmp指向RGB的最末一行
    char *tmp = rgb+lineBytes*(info.height-1);
    // 将RGB数据显示到LCD上
    for(int j=0; j<info.height && j<480; j++){
        // LCD显示的行号
        int lcd_lines = 800*4*(j+mid_y);
        for(int i=0; i<info.width && i<800; i++){
            memcpy(p+4*i + lcd_lines + mid_x*4 , tmp+3*i*p_wd, 3);
        }
        // 让tmp指向上一行
        tmp -= lineBytes*p_ht;
    }
    return 0;
}
